import { useRef, useState, useEffect } from 'react';
// import EmojiPicker from 'emoji-picker-react';
import './VoiceChat.css';
import { AudioOutlined } from '@ant-design/icons';

type Message = { from: 'user' | 'ai'; text: string };

interface VoiceChatProps {
  setAnimation?: (anim: string) => void;
  lang?: 'zh' | 'en';
}

// WebSocket服务地址（如需部署到服务器请修改此处）
// const WS_SERVER_URL = 'ws://localhost:8000'; // 不再需要WebSocket
const HTTP_AI_CHAT_URL = 'http://localhost:8000/api/ai-chat';

// 顶部添加类型声明（兼容 TS 环境）
type _SpeechRecognition = typeof window extends { webkitSpeechRecognition: infer T } ? T : any;
type _SpeechRecognitionEvent = typeof window extends { webkitSpeechRecognitionEvent: infer T } ? T : any;
declare global {
  interface Window {
    webkitSpeechRecognition: any;
    SpeechRecognition: any;
    webkitSpeechRecognitionEvent: any;
  }
}

// 在AI回复后自动分析动作关键词并控制3D人物动画
const actionKeywords = [
  { key: '跳舞', action: 'dance' },
  { key: '舞蹈', action: 'dance' },
  { key: '待机', action: 'idle' },
  { key: '休息', action: 'idle' },
  { key: '哭', action: 'crying' },
  { key: '哭泣', action: 'crying' },
  { key: '伤心', action: 'crying' },
  { key: '倒立', action: 'breakDance' },
  { key: '翻跟头', action: 'breakDance' },
  { key: '特技', action: 'breakDance' },
  { key: '杂技', action: 'breakDance' },
  { key: '翻转', action: 'breakDance' },
  { key: '说话', action: 'speaking' },
  { key: '聊天', action: 'speaking' },
  { key: '对话', action: 'speaking' },
  { key: '交流', action: 'speaking' },
  { key: '谈谈', action: 'speaking' },
];
function detectActionFromText(text: string): string | null {
  for (const item of actionKeywords) {
    if (text.includes(item.key)) return item.action;
  }
  return null;
}

const VoiceChat: React.FC<VoiceChatProps> = ({ setAnimation, lang = 'zh' }) => {
  const [show, setShow] = useState(false);
  const [recording, setRecording] = useState(false);
  const [voiceText, setVoiceText] = useState('');
  const [messages, setMessages] = useState<Message[]>([]);
  const [isListening, setIsListening] = useState(false); // 持续监听状态
  const recognitionRef = useRef<_SpeechRecognition | null>(null);
  const wakeupRecognitionRef = useRef<_SpeechRecognition | null>(null); // 唤醒词识别
  const [textInput, setTextInput] = useState(''); // 新增：文字输入框内容
  const chatScrollRef = useRef<HTMLDivElement | null>(null);
  // const ws = useRef<WebSocket | null>(null); // 删除ws相关useRef

  // 智能动作指令识别
  const smartActionRecognition = (text: string) => {
    const lowerText = text.toLowerCase();
    
    // 跳舞相关指令
    if (lowerText.includes('跳舞') || lowerText.includes('舞蹈') || lowerText.includes('表演') || 
        lowerText.includes('展示') || lowerText.includes('动起来') || lowerText.includes('跳个舞') ||
        lowerText.includes('来跳舞') || lowerText.includes('跳支舞') || lowerText.includes('舞动')) {
      return { action: 'dance', response: '好的，我来为您跳舞！' };
    }
    
    // 停止/待机相关指令
    if (lowerText.includes('停止') || lowerText.includes('别动') || lowerText.includes('安静') || 
        lowerText.includes('休息') || lowerText.includes('待机') || lowerText.includes('停下') ||
        lowerText.includes('不要动') || lowerText.includes('静止')) {
      return { action: 'idle', response: '好的，我安静待机。' };
    }
    
    // 哭泣相关指令
    if (lowerText.includes('哭泣') || lowerText.includes('哭') || lowerText.includes('伤心') ||
        lowerText.includes('难过') || lowerText.includes('悲伤')) {
      return { action: 'crying', response: '呜呜，我有点伤心...' };
    }
    
    // 倒立相关指令
    if (lowerText.includes('倒立') || lowerText.includes('翻跟头') || lowerText.includes('特技') ||
        lowerText.includes('杂技') || lowerText.includes('翻转')) {
      return { action: 'breakDance', response: '看我的倒立表演！' };
    }
    
    // 说话相关指令
    if (lowerText.includes('说话') || lowerText.includes('聊天') || lowerText.includes('对话') ||
        lowerText.includes('交流') || lowerText.includes('谈谈')) {
      return { action: 'speaking', response: '我在听您说话，请继续...' };
    }
    
    return null;
  };

  // 检查是否为动作指令
  const isActionCommand = (text: string): boolean => {
    return smartActionRecognition(text) !== null;
  };

  // 执行动作指令
  const executeActionCommand = (text: string) => {
    const result = smartActionRecognition(text);
    if (result) {
      console.log(`执行动作指令: ${text} -> ${result.action}`);
      if (setAnimation) {
        setAnimation(result.action);
      }
      return result;
    }
    return null;
  };

  // 优化天气查询API，支持自动识别城市
  const fetchWeather = async (textOrCity: string = '北京') => {
    // 尝试从输入中提取城市名
    let city = '北京';
    // 匹配“XX天气”或“查询XX天气”
    const match = textOrCity.match(/([\u4e00-\u9fa5]{2,10})?\s*天气/);
    if (match && match[1]) {
      city = match[1];
    } else if (/weather in ([a-zA-Z]+)/i.test(textOrCity)) {
      city = textOrCity.match(/weather in ([a-zA-Z]+)/i)?.[1] || 'Beijing';
    } else if (textOrCity.length > 0 && textOrCity.length < 20 && !textOrCity.includes('天气')) {
      city = textOrCity;
    }
    try {
      const key = 'free-api-key'; // 替换为你的和风天气key
      const url = `https://devapi.qweather.com/v7/weather/now?location=${encodeURIComponent(city)}&key=${key}`;
      const res = await fetch(url);
      const data = await res.json();
      if (data && data.now) {
        return `${city}当前天气：${data.now.text}，气温${data.now.temp}℃，风力${data.now.windScale}级`;
      } else if (data && data.code === '404') {
        return `未找到${city}的天气信息`;
      } else {
        return '未能获取天气信息';
      }
    } catch (e) {
      return '天气服务异常';
    }
  };

  // 语音识别
  const startRecognition = () => {
    const SpeechRecognition =
      (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;
    console.log('SpeechRecognition:', SpeechRecognition);
    if (!SpeechRecognition) {
      alert('当前浏览器不支持语音识别');
      return;
    }
    const recognition = new SpeechRecognition();
    recognition.lang = 'zh-CN';
    recognition.interimResults = false;
    recognition.maxAlternatives = 1;
    recognition.onresult = async (event: _SpeechRecognitionEvent) => {
      console.log('识别结果事件:', event);
      if (event.results && event.results[0] && event.results[0][0]) {
        const text = event.results[0][0].transcript;
        console.log('识别文本:', text);
        setVoiceText(text);
        setMessages((h) => [...h, { from: 'user', text }]);
        
        // 检查是否为动作指令
        if (isActionCommand(text)) {
          const action = executeActionCommand(text);
          if (action) {
            // 添加动作执行反馈
            setMessages((h) => [...h, { from: 'ai', text: action.response }]);
            // 如果是说话动作，播放语音反馈
            if (action.action === 'speaking') {
              speakText(action.response);
            }
          }
        } else if (text.includes('天气')) {
          // 天气查询
          const weather = await fetchWeather(text);
          setMessages((h) => [...h, { from: 'ai', text: weather }]);
          speakText(weather);
        } else {
          // 不是动作指令，发送给AI聊天
          sendToAI(text);
        }
      } else {
        console.warn('未识别到文本');
      }
    };
    recognition.onerror = (e: { error?: string }) => {
      console.error('语音识别错误:', e);
      setRecording(false);
    };
    recognition.onend = () => {
      console.log('语音识别结束');
      setRecording(false);
    };
    recognition.onaudiostart = () => console.log('音频捕获开始');
    recognition.onaudioend = () => console.log('音频捕获结束');
    recognition.onsoundstart = () => console.log('检测到声音');
    recognition.onsoundend = () => console.log('声音结束');
    recognition.onspeechstart = () => console.log('检测到语音');
    recognition.onspeechend = () => console.log('语音结束');
    recognitionRef.current = recognition;
    recognition.start();
    setRecording(true);
    setVoiceText('');
    console.log('语音识别已启动');
  };

  const stopRecognition = () => {
    console.log('手动停止语音识别');
    recognitionRef.current?.stop();
    setRecording(false);
  };

  // 发送到AI（WebSocket方式，自动等待连接）
  const sendToAI = async (text: string) => {
    setMessages((h) => [...h, { from: 'ai', text: '思考中...' }]);
    try {
      const res = await fetch(HTTP_AI_CHAT_URL, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ message: text }),
      });
      const data = await res.json();
      if (data.reply) {
        setMessages((h) => [...h.slice(0, -1), { from: 'ai', text: data.reply }]);
        speakText(data.reply);
        // 检查AI回复内容中的动作关键词
        if (setAnimation) {
          const anim = detectActionFromText(data.reply);
          if (anim) setAnimation(anim);
        }
      } else if (data.error) {
        setMessages((h) => [...h.slice(0, -1), { from: 'ai', text: data.error }]);
      } else {
        setMessages((h) => [...h.slice(0, -1), { from: 'ai', text: 'AI无回复' }]);
      }
    } catch (err) {
      setMessages((h) => [...h.slice(0, -1), { from: 'ai', text: 'AI服务连接失败' }]);
    }
  };

  //
  // TTS
  const speakText = (text: string) => {
    console.log('TTS朗读:', text);
    if ('speechSynthesis' in window) {
      if (setAnimation) setAnimation('speaking'); // 朗读时让数字人动起来
      const utter = new window.SpeechSynthesisUtterance(text);
      utter.lang = 'zh-CN';
      utter.onstart = () => console.log('TTS开始朗读');
      utter.onend = () => {
        console.log('TTS朗读结束');
        if (setAnimation) setAnimation('idle'); // 朗读结束后恢复待机
      };
      utter.onerror = (e) => {
        console.error('TTS朗读错误:', e);
        if (setAnimation) setAnimation('idle');
      };
      window.speechSynthesis.speak(utter);
    } else {
      console.warn('当前浏览器不支持TTS语音合成');
    }
  };

  // 启动唤醒词监听
  const startWakeupListening = () => {
    if (isListening) return; // 如果已经在监听，直接返回
    
    const SpeechRecognition =
      (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;
    
    if (!SpeechRecognition) {
      console.warn('当前浏览器不支持语音识别');
      return;
    }

    const recognition = new SpeechRecognition();
    recognition.lang = 'zh-CN';
    recognition.interimResults = true; // 启用中间结果
    recognition.continuous = true; // 持续监听
    recognition.maxAlternatives = 1;

    recognition.onresult = (event: _SpeechRecognitionEvent) => {
      let finalTranscript = '';
      let interimTranscript = '';

      for (let i = event.resultIndex; i < event.results.length; i++) {
        const transcript = event.results[i][0].transcript;
        if (event.results[i].isFinal) {
          finalTranscript += transcript;
        } else {
          interimTranscript += transcript;
        }
      }

      // 检查唤醒词
      const fullText = (finalTranscript + interimTranscript).toLowerCase();
      if (
        fullText.includes('小薇小薇') ||
        fullText.includes('小微小微') ||
        fullText.includes('小威小威') ||
        fullText.includes('小萌小萌')
      ) {
        console.log('检测到唤醒词:', fullText);
        stopWakeupListening();
        setShow(true);
        setTimeout(() => startRecognition(), 100);
      }
    };

    recognition.onerror = (e: { error?: string }) => {
      console.error('唤醒词识别错误:', e);
      if (e.error === 'no-speech') {
        // 如果没有检测到语音，重新启动监听
        setTimeout(() => {
          if (!isListening) {
            startWakeupListening();
          }
        }, 1000);
      }
    };

    recognition.onend = () => {
      console.log('唤醒词识别结束，重新启动');
      if (isListening && !show) {
        // 如果还在监听状态且聊天窗口未打开，重新启动
        setTimeout(() => startWakeupListening(), 1000);
      }
    };

    wakeupRecognitionRef.current = recognition;
    recognition.start();
    setIsListening(true);
    console.log('启动唤醒词监听');
  };

  // 停止唤醒词监听
  const stopWakeupListening = () => {
    if (wakeupRecognitionRef.current) {
      wakeupRecognitionRef.current.stop();
      wakeupRecognitionRef.current = null;
    }
    setIsListening(false);
    console.log('停止唤醒词监听');
  };

  // 新增：文字输入发送
  const handleTextSend = async () => {
    if (!textInput.trim()) return;
    setMessages((h) => [...h, { from: 'user', text: textInput }]);
    if (textInput.includes('天气')) {
      const weather = await fetchWeather(textInput);
      setMessages((h) => [...h, { from: 'ai', text: weather }]);
      speakText(weather);
      setTextInput('');
      return;
    }
    sendToAI(textInput);
    setTextInput('');
  };

  // 组件挂载时启动唤醒词监听
  useEffect(() => {
    startWakeupListening();
    
    return () => {
      stopWakeupListening();
    };
  }, []);

  // 当聊天窗口关闭时，重新启动唤醒词监听
  useEffect(() => {
    if (!show && !isListening) {
      setTimeout(() => startWakeupListening(), 1000);
    }
  }, [show, isListening]);

  // 删除所有ws.current相关逻辑
  // useEffect(() => {
  //   ws.current = new window.WebSocket(WS_SERVER_URL);
  //   ws.current.onmessage = (event) => {
  //     const data = JSON.parse(event.data);
  //     if (data.reply) {
  //       setMessages((h) => [...h.slice(0, -1), { from: 'ai', text: data.reply }]);
  //       speakText(data.reply);
  //     } else if (data.error) {
  //       setMessages((h) => [...h.slice(0, -1), { from: 'ai', text: data.error }]);
  //     }
  //   };
  //   ws.current.onerror = () => {
  //     setMessages((h) => [...h.slice(0, -1), { from: 'ai', text: 'WebSocket连接失败' }]);
  //   };
  //   return () => ws.current?.close();
  // }, []);

  useEffect(() => {
    if (chatScrollRef.current) {
      chatScrollRef.current.scrollTop = chatScrollRef.current.scrollHeight;
    }
  }, [messages]);

  return (
    <>
      <button
        className={`voicechat-mic-btn${recording ? ' recording' : ''}`}
        style={{
          position: 'absolute',
          left: '50%',
          bottom: '8%',
          transform: 'translateX(-50%)',
          zIndex: 100,
          borderRadius: 40,
          width: 80,
          height: 80,
          background: recording ? '#fff0f0' : 'rgba(255,255,255,0.95)',
          border: 'none',
          padding: 0,
          boxShadow: recording ? '0 0 0 0 #f5222d44' : '0 2px 12px rgba(0,0,0,0.18)',
          transition: 'box-shadow 0.2s, background 0.2s',
          outline: recording ? '2px solid #f5222d' : 'none',
          cursor: 'pointer',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}
        onClick={() => {
          setShow(true);
          setTimeout(() => startRecognition(), 100);
        }}
        aria-label={lang === 'zh' ? '语音聊天' : 'Voice Chat'}
        title={lang === 'zh' ? '语音聊天' : 'Voice Chat'}
      >
        <AudioOutlined style={{ fontSize: 40, color: recording ? '#f5222d' : '#409EFF', transition: 'color 0.2s' }} />
      </button>
      {show && (
        <div
          style={{
            position: 'fixed',
            left: 0,
            top: 0,
            width: '100vw',
            height: '100vh',
            background: 'rgba(0,0,0,0.3)',
            zIndex: 1001,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
          }}
          onClick={() => setShow(false)}
        >
          <div
            style={{
              background: '#fff',
              borderRadius: 16,
              padding: 24,
              width: 350,
              minHeight: 400,
              boxShadow: '0 8px 32px rgba(0,0,0,0.15)',
              display: 'flex',
              flexDirection: 'column',
              position: 'relative',
            }}
            onClick={(e) => e.stopPropagation()}
          >
            <div style={{ fontWeight: 600, fontSize: 22, marginBottom: 12 }}>{lang === 'zh' ? '语音聊天' : 'Voice Chat'}</div>
            
            {/* 添加动作指令提示 */}
            <div style={{ 
              background: '#f0f8ff', 
              borderRadius: 8, 
              padding: 8, 
              marginBottom: 12,
              fontSize: 12,
              color: '#666'
            }}>
              <div style={{ fontWeight: 600, marginBottom: 4 }}>{lang === 'zh' ? '🎯 可用指令：' : '🎯 Available Commands:'}</div>
              <div style={{ lineHeight: 1.4 }}>
                <div>💃 <strong>{lang === 'zh' ? '跳舞' : 'Dance'}</strong>：{lang === 'zh' ? '跳舞、舞蹈、表演、展示、动起来、跳个舞' : 'dance, performance, show, move, dance please'}</div>
                <div>😴 <strong>{lang === 'zh' ? '待机' : 'Idle'}</strong>：{lang === 'zh' ? '停止、别动、安静、休息、待机、停下' : 'stop, don\'t move, quiet, rest, idle, pause'}</div>
                <div>😢 <strong>{lang === 'zh' ? '哭泣' : 'Crying'}</strong>：{lang === 'zh' ? '哭泣、哭、伤心、难过、悲伤' : 'cry, sad, unhappy, sorrow'}</div>
                <div>🤸 <strong>{lang === 'zh' ? '倒立' : 'Breakdance'}</strong>：{lang === 'zh' ? '倒立、翻跟头、特技、杂技、翻转' : 'breakdance, flip, stunt, acrobatics, turn over'}</div>
                <div>💬 <strong>{lang === 'zh' ? '说话' : 'Speak'}</strong>：{lang === 'zh' ? '说话、聊天、对话、交流、谈谈' : 'speak, chat, talk, communicate'}</div>
              </div>
            </div>
            
            <div
              ref={chatScrollRef}
              style={{
                flex: 1,
                overflowY: 'auto',
                marginBottom: 12,
                background: '#f5f5f5',
                borderRadius: 8,
                padding: 8,
                maxHeight: 260,
                scrollbarWidth: 'thin', // Firefox
                scrollbarColor: '#b3c6ff #f5f5f5', // Firefox
              }}
              className="voicechat-scroll"
            >
              {messages.map((msg, idx) => (
                <div
                  key={idx}
                  style={{
                    textAlign: msg.from === 'user' ? 'right' : 'left',
                    margin: '6px 0',
                  }}
                >
                  <span
                    style={{
                      background: msg.from === 'user' ? '#3a8bff' : '#e9ecef',
                      color: msg.from === 'user' ? '#fff' : '#333',
                      borderRadius: 12,
                      padding: '6px 12px',
                      fontSize: 15,
                      maxWidth: 200,
                      wordBreak: 'break-all',
                      display: 'inline-block',
                    }}
                  >
                    {msg.text}
                  </span>
                </div>
              ))}
            </div>
            {/* 新增：文字输入框和发送按钮 */}
            <div style={{ display: 'flex', gap: 8, marginBottom: 8 }}>
              <input
                type="text"
                value={textInput}
                onChange={e => setTextInput(e.target.value)}
                onKeyDown={e => { if (e.key === 'Enter') handleTextSend(); }}
                placeholder={lang === 'zh' ? '请输入内容...' : 'Type a message...'}
                style={{ flex: 1, borderRadius: 8, border: '1px solid #eee', padding: 8, fontSize: 15 }}
                autoFocus
              />
              <button
                onClick={handleTextSend}
                style={{ background: '#3a8bff', color: '#fff', border: 'none', borderRadius: 8, padding: '0 18px', fontSize: 15, cursor: 'pointer' }}
                disabled={!textInput.trim()}
              >{lang === 'zh' ? '发送' : 'Send'}</button>
            </div>
            <div style={{ marginBottom: 12, color: '#888', minHeight: 24 }}>
              {recording
                ? '🎤 正在听您说话...'
                : voiceText
                  ? `✅ 识别结果：${voiceText}`
                  : '🎯 请直接说话，系统会自动识别'}
            </div>
            
            {/* 右上角关闭按钮 */}
            <button
              style={{
                position: 'absolute',
                top: 12,
                right: 16,
                background: 'transparent',
                border: 'none',
                fontSize: 22,
                color: '#888',
                cursor: 'pointer',
                zIndex: 10,
              }}
              onClick={() => {
                setShow(false);
                stopRecognition();
                setTimeout(() => startWakeupListening(), 1000);
              }}
              title="关闭"
            >
              ×
            </button>
            <button
              style={{
                width: '100%',
                height: 36,
                borderRadius: 8,
                fontSize: 15,
                background: '#3a8bff',
                color: '#fff',
                border: 'none',
                marginTop: 0,
                marginBottom: 8,
                cursor: 'pointer',
              }}
              onClick={() => {
                startRecognition();
              }}
            >
              🎤 继续语音
            </button>
          </div>
        </div>
      )}
      {/* <EmojiPicker
        onEmojiClick={e => {
          setDanmuInput(danmuInput + e.emoji);
          setShowEmoji(false);
        }}
        height={350}
        emojiStyle="native"
      /> */}
    </>
  );
};

export default VoiceChat;
